package cn.good.yan.config.filters;

import cn.good.yan.config.pg.WhiteListConfig;
import cn.good.yan.entity.UserLogin;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 授权过滤器，- 全局过滤器配置 （全局过滤器）
 * 授权过滤
 *
 * @author shengren.yan
 * @create 2024/11/23
 */
@Slf4j
@Component
public class MyPermissionFilter implements GlobalFilter, Ordered {


    // 获取白名单列表
    @Autowired
    private WhiteListConfig whiteListConfig;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 获取当前路径
        String mrPath = Optional.ofNullable(exchange.getRequest().getURI().getPath())
                .orElse(" Illegal path");

        // 获得请求和响应对象
        ServerHttpRequest request = exchange.getRequest();
        // 对白名单中的地址放行 （白名单）
        List<String> whiteList = whiteListConfig.getWhiteList();
        for (String str : whiteList) {
            String path = request.getURI().getPath();  // 获取请求地址
            if (path.contains(str)) {
                log.info("白名单，放行{}", request.getURI().getPath());
                return chain.filter(exchange);
            }
        }

        // 可以把当前用户存到Redis，从Redis中获取权限列表，进行比较
        // 获取权限列表 （目前演示，得到用户名，）
        String loginUser = Optional.ofNullable((UserLogin) exchange.getAttributes().get("loginUser"))
                .map(UserLogin::getUsername)
                .orElse(null);

        // 如果拥有权限则放行
        List<String> permissionList = new ArrayList<>();
        permissionList.add(loginUser);
        permissionList.add(mrPath);
        if (hasPermission(permissionList, mrPath)) {
            return chain.filter(exchange);
        }

        //如果不存在则拦截
        return out(exchange.getResponse(), "权限不足或路径不存在");
    }


    //权限列表是否拥有权限访问路径的权限
    public static boolean hasPermission(List<String> permissionList, String path) {
        // 匹配路径
//        return permissionList.stream().anyMatch(s -> s.equals(path));
//        return permissionList.contains(path);
        return permissionList.contains("/order9003/order/list");

    }

    // 返回体
    public static Mono<Void> out(ServerHttpResponse response, String data) {
        JSONObject message = new JSONObject();
        message.append("success", false);
        message.append("code", 28004);
        message.append("data", data);
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 这个返回的数值越小，上面的filter优先级就越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }

}
